/**
 * vite.config.ts
 */
import path from "path"
import { defineConfig } from "vite"
import { loadEnv, UserConfig, ConfigEnv } from "vite"

import vue from "@vitejs/plugin-vue"
import vueJsx from "@vitejs/plugin-vue-jsx"
import vueDevTools from "vite-plugin-vue-devtools"

import { viteStaticCopy } from "vite-plugin-static-copy"
import { createSvgIconsPlugin } from "vite-plugin-svg-icons"

import AutoImport from "unplugin-auto-import/vite"
import Components from "unplugin-vue-components/vite"
import { VantResolver } from "unplugin-vue-components/resolvers"
// ----------------------------------------------------------------------------
const ROOT = path.resolve(process.cwd(), "")
const SRC = path.resolve(ROOT, "src")
const OUT = path.resolve(ROOT, "dist")
const ENV = path.resolve(ROOT, "env")
const CACHE = path.resolve(ROOT, "cache")
const PUBLIC = path.resolve(ROOT, "public")

const OUT_ASSETS_FOLDER = "build" // 指定生成静态资源的存放路径 (相对于 build.outDir)
const NODE_ENV = process.env.NODE_ENV as string
// const isProduction = NODE_ENV === "production"
// console.log(`NODE_ENV = ${isProduction}`)

// 用于 sgv-icon
const SvgIconDirs = [
    path.resolve(ROOT, "src/assets/svgs"),
    path.resolve(ROOT, "src/assets/svgicons/common"),
    path.resolve(ROOT, "src/assets/svgicons/flags"),
]
// ----------------------------------------------------------------------------
const buildUserConfig = (node_env?: string): UserConfig => {
    //
    const MODE = node_env ?? ("production" as string)
    const isprod = MODE === "production"
    const viteEnv = loadViteEnv(MODE, ENV)
    //
    const result: UserConfig = {
        appType: "spa", // APP 类型
        root: ROOT, // 项目根目录（index.html 文件所在的位置）
        envDir: ENV, // 环境文件(.env.*)目录
        cacheDir: CACHE, // 存储缓存文件的目录
        publicDir: PUBLIC, // 静态资源服务的文件夹, 在构建期间复制到 build.outDir 的根目录
        mode: MODE,
        assetsInclude: ["**/*.gltf"], // 包含的资产

        resolve: {
            alias: {
                ["@"]: SRC,
                ["vue-i18n"]: "vue-i18n/dist/vue-i18n.cjs.js", // 解决i8n警告 ...vue-i18n.esm-bundler.js
            },
            // 导入时想要省略的扩展名列表
            extensions: [".mjs", ".js", ".mts", ".ts", ".jsx", ".tsx", ".json"],
        },

        css: {
            // CSS 模块化
            modules: {
                scopeBehaviour: "global",
            },
            // CSS 预处理器的选项
            preprocessorOptions: {
                scss: {
                    // 隐藏 Deprecation Warning: The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0.
                    api: "modern-compiler",
                    // 预编译支持 scss
                    // additionalData: '@import "src/styles/variables.module.scss";',
                    // javascriptEnabled: true, // 支持内联 JavaScript
                },
                less: {
                    // 预编译支持less
                    // additionalData: '@import "@/styles/variables.module.less";',
                    // javascriptEnabled: true, // 支持内联 JavaScript
                },
            },
            // CSS sourcemaps enabled during dev
            devSourcemap: true,
        },

        plugins: [
            vue(),
            vueJsx(),
            vueDevTools(),
            AutoImport({
                imports: ["vue"],
                dts: "src/autotypes/auto-imports.d.ts",
                resolvers: [VantResolver()],
            }),
            Components({
                dts: "src/autotypes/auto-components.d.ts",
                resolvers: [
                    // 自动导入 Vant 组件
                    VantResolver(),
                ],
            }),
            // Icons(),
            // 静态资源拷贝
            viteStaticCopy({
                targets: [{ src: ["LICENSE"], dest: "" }],
            }),
            // createHtmlPlugin({
            //     minify: true,
            //     inject: {
            //         data: {
            //             app_title: viteEnv.VITE_APP_TITLE,
            //         },
            //     },
            // }),
            // 使用本地 svg 作为图标 icon
            createSvgIconsPlugin({
                iconDirs: SvgIconDirs,
                symbolId: "icon-[dir]-[name]", // default: icon-[dir]-[name]
            }),
        ],

        /** Server Options */
        server: {
            host: "0.0.0.0", // 项目运行地址，此处代表 localhosto
            port: viteEnv.VITE_PORT, // 项目运行端口 default = 5173 ()
            open: viteEnv.VITE_OPEN, // 运行 npm run dev 时是否自动打开浏览器
            hmr: viteEnv.VITE_HMR, // 是否开启热加载
            strictPort: false, // 设为 true 时若端口已被占用则会直接退出
            https: undefined, // 启用 TLS + HTTP/2
            cors: true, // 默认启用并允许任何源
            proxy: undefined, // 跨域代理配置,期望接收一个 { key: options }
        },

        build: {
            outDir: OUT, // 指定输出路径, 默认 dist
            minify: isprod ? "esbuild" : false, // specify the minifier to use
            assetsDir: OUT_ASSETS_FOLDER, // 指定生成静态资源的存放路径 (相对于 build.outDir)
            cssCodeSplit: true, // 配置 CSS 代码拆分
            sourcemap: false, // 构建后是否生成 source map 文件, default false
            manifest: true, // 构建后将会生成 manifest.json 文件, 默认 false (OUT/.vite/manifest.json)
            copyPublicDir: true, // 在构建阶段将 public 目录中的所有文件复制到 outDir 目录中
            chunkSizeWarningLimit: 1500, // 调整区块大小警告限制 (in kbs).
            rollupOptions: {
                input: undefined,
                // 自定义底层的 Rollup 打包配置
                output: {
                    chunkFileNames: `${OUT_ASSETS_FOLDER}/js/chunk-[name]-[hash].js`,
                    entryFileNames: `${OUT_ASSETS_FOLDER}/js/entry-[name]-[hash].js`,
                    assetFileNames: `${OUT_ASSETS_FOLDER}/[ext]/[name]-[hash].[ext]`,
                    // https://rollupjs.org/guide/en/#outputmanualchunks
                    manualChunks: {
                        utils: ["./src/utils"],
                        // "group-user": ["./src/UserDetails", "./src/UserDashboard", "./src/UserProfileEdit"],
                    },
                },
                external: [],
            },
        },

        esbuild: {
            // 打包去除 console.log && debugger
            pure: viteEnv.VITE_DROP_CONSOLE ? ["console.log", "console.trace", "debugger"] : [],
        },

        // 自定义
        define: {
            DEMO_BOOL: true,
            DEMO_NUMBER: 20,
            DEMO_ARRAY: [1, 2, 3],
            DEMO_OBJECT: { name: "asc" },
            DEMO_STRING: JSON.stringify("This is demo string..."),
        },
    }

    return result as UserConfig
}
const userConfig = buildUserConfig(process.env.NODE_ENV)
export default defineConfig(userConfig)

// https://vite.dev/config/
const c1 = defineConfig({
    cacheDir: CACHE,
    plugins: [
        vue(),
        vueJsx(),
        vueDevTools(),
        AutoImport({
            imports: ["vue"],
            dts: "src/autotypes/auto-imports.d.ts",
            resolvers: [VantResolver()],
        }),
        Components({
            dts: "src/autotypes/auto-components.d.ts",
            resolvers: [VantResolver()],
        }),
        // 静态资源拷贝
        viteStaticCopy({
            targets: [{ src: ["LICENSE"], dest: "" }],
        }),
    ],
    resolve: {
        alias: {
            ["@"]: SRC,
        },
    },
    server: {
        port: 6807,
    },
})

export { c1 }
// ----------------------------------------------------------------------------
/**
 * 装载自定义环境信息
 * @param custom_node_env 在 package.json 文件 scripts 中定义的 `NODE_ENV`
 * @param envPath env 文件路径
 * @returns Vite Env 信息 {@link ViteEnv}
 * @description 根据在 package.json 文件 scripts 中定义的 `NODE_ENV`
 * 选择自定义环境信息文件 (.env & .env.development || .env.production || .env.test)
 */
function loadViteEnv(custom_node_env: string, envPath: string): ViteEnv {
    //
    const result: Partial<ViteEnv> = {}
    // ----------------------------------------------------
    // 根据 process.env.NODE_ENV 选择装载 envdir 目录下面的
    // env 文件 (.env.development / .env.production / .env.test)
    // NODE_ENV = development | production | test 等
    const _env = loadEnv(custom_node_env, envPath) as Record<string, any>
    // const _env = loadEnv(NODE_ENV, ENVDIR) as Record<string, any>;

    // 解析数据
    for (const env_key of Object.keys(_env)) {
        //
        let env_value = _env[env_key].replace(/\\n/g, "\n")

        // 转换 boolean 类型
        env_value = env_value === "true" ? true : env_value === "false" ? false : env_value

        // 转换 number 类型
        if (env_key === "VITE_PORT") {
            env_value = Number(env_value)
        }

        // 代理服务器
        if (env_key === "VITE_PROXY") {
            try {
                env_value = JSON.parse(env_value)
            } catch (error) {
                // throw error;
            }
        }

        //
        result[env_key] = env_value
    }
    // ----------------------------------------------------
    return result as ViteEnv
}
